package com.lottery.service;

import com.lottery.entity.LotteryRecord;
import com.lottery.entity.Prize;
import com.lottery.entity.User;
import com.lottery.entity.UserChance;
import com.lottery.repository.LotteryRecordRepository;
import com.lottery.repository.PrizeRepository;
import com.lottery.repository.UserChanceRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Random;

@Service
@Transactional
public class LotteryService {

    @Autowired
    private PrizeRepository prizeRepository;

    @Autowired
    private LotteryRecordRepository lotteryRecordRepository;

    @Autowired
    private UserChanceRepository userChanceRepository;

    @Autowired
    private UserService userService;

    private final Random random = new Random();

    /**
     * 执行抽奖
     */
    public LotteryRecord drawLottery(Long userId) {
        User user = userService.findById(userId);
        
        // 检查用户是否有抽奖机会
        UserChance userChance = getUserChance(userId);
        if (userChance.getChances() <= 0) {
            throw new RuntimeException("您的抽奖次数已用完");
        }

        // 获取所有可用奖品
        List<Prize> availablePrizes = prizeRepository.findAvailablePrizes();
        if (availablePrizes.isEmpty()) {
            throw new RuntimeException("暂无可用奖品");
        }

        // 执行抽奖逻辑
        Prize wonPrize = performLottery(availablePrizes);
        
        // 减少用户抽奖次数
        userChance.setChances(userChance.getChances() - 1);
        userChanceRepository.updateById(userChance);

        // 创建抽奖记录
        LotteryRecord record = new LotteryRecord();
        record.setUserId(userId);
        
        if (wonPrize != null) {
            // 中奖了
            record.setPrizeId(wonPrize.getId());
            record.setPrizeName(wonPrize.getName());
            record.setIsWinner(true);
            
            // 减少奖品数量
            wonPrize.setRemaining(wonPrize.getRemaining() - 1);
            prizeRepository.updateById(wonPrize);
        } else {
            // 未中奖
            record.setPrizeName("谢谢参与");
            record.setIsWinner(false);
        }

        lotteryRecordRepository.insert(record);
        return record;
    }

    /**
     * 抽奖算法
     */
    private Prize performLottery(List<Prize> availablePrizes) {
        // 计算总概率
        double totalProbability = availablePrizes.stream()
                .mapToDouble(prize -> prize.getProbability().doubleValue())
                .sum();

        // 生成随机数
        double randomValue = random.nextDouble() * totalProbability;
        
        // 根据概率选择奖品
        double currentProbability = 0;
        for (Prize prize : availablePrizes) {
            currentProbability += prize.getProbability().doubleValue();
            if (randomValue <= currentProbability) {
                return prize;
            }
        }
        
        // 如果没有中奖，返回null
        return null;
    }

    /**
     * 获取用户抽奖次数
     */
    public UserChance getUserChance(Long userId) {
        UserChance userChance = userChanceRepository.findByUserId(userId);
        if (userChance == null) {
            // 如果用户没有抽奖次数记录，创建一个默认的
            UserChance newChance = new UserChance();
            newChance.setUserId(userId);
            newChance.setChances(3); // 默认3次机会
            userChanceRepository.insert(newChance);
            return newChance;
        }
        return userChance;
    }

    /**
     * 增加用户抽奖次数
     */
    public void addUserChances(Long userId, int chances) {
        UserChance userChance = getUserChance(userId);
        userChance.setChances(userChance.getChances() + chances);
        userChanceRepository.updateById(userChance);
    }

    /**
     * 获取用户抽奖记录
     */
    public List<LotteryRecord> getUserLotteryRecords(Long userId) {
        return lotteryRecordRepository.findByUserIdOrderByCreatedAtDesc(userId);
    }

    /**
     * 获取所有奖品
     */
    public List<Prize> getAllPrizes() {
        return prizeRepository.findAllOrderByProbabilityDesc();
    }

    /**
     * 获取可用奖品
     */
    public List<Prize> getAvailablePrizes() {
        return prizeRepository.findAvailablePrizes();
    }

    /**
     * 根据ID获取奖品
     */
    public Prize getPrizeById(Long prizeId) {
        return prizeRepository.selectById(prizeId);
    }
}